/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package sml;

/**
 *
 * @author Jose Carlos Palma
 */
public class CPU {

    /**
     * Input Operation, Read a word from the keyboard into a specific location
     * in memory.
     */
    public static final int READ = 10;
    /**
     * Output Operation, Write a word from a specific location in memory to the
     * screen.
     */
    public static final int WRITE = 11;
    /**
     * Load Operation, Load a word from a specific location in memory into the
     * accumulator.
     */
    public static final int LOAD = 20;
    /**
     * Store Operation, Store a word from the accumulator into a specific loca-
     * tion in memory.
     */
    public static final int STORE = 21;
    /**
     * Add Operation, Add a word from a specific location in memory to the word
     * in the accumulator (leave the result in the accumu- lator).
     */
    public static final int ADD = 30;
    /**
     * Subtract Operation, Subtract a word from a specific location in memory
     * from the word in the accumulator (leave the result in the accu- mulator).
     */
    public static final int SUBTRACT = 31;
    /**
     * Divive OPeration, Divide a word from a specific location in memory into
     * the word in the accumulator (leave result in the accumulator).
     */
    public static final int DIVIDE = 32;
    /**
     * Multiply OPeration, Multiply a word from a specific location in memory by
     * the word in the accumulator (leave the result in the accumulator).
     */
    public static final int MULTIPLY = 33;
    /**
     * Branch to a specific location in memory.
     */
    public static final int BRANCH = 40;
    /**
     * Branch to a specific location in memory if the accumulator is negative.
     */
    public static final int BRANCHNEG = 41;
    /**
     * Branch to a specific location in memory if the accumulator is zero.
     */
    public static final int BRANCHZERO = 42;
    /**
     * Halt. The program has completed its task.
     */
    public static final int HALT = 50;
    private int accumulator = 0;
    private int pointer = 0;
    private int instruction = 0;
    private int operationCode = 0;
    private int operand = 0;

    public CPU() {
    }

    public void execute(Ram ram) {
        do{
            
            instruction = ram.get(pointer++);
            operationCode = instruction / 100;
            operand = instruction % 100;
            
            switch (operationCode) {
                case READ:
                    int val = Keyboard.readInteger("Enter an integer ");
                    ram.set(operand, val);
                    break;
                case WRITE:
                    Screen.print(ram.get(operand));
                    break;
                case LOAD:
                    accumulator = ram.get(operand);
                    break;
                case STORE:
                    ram.set(operand, accumulator);
                    break;
                case ADD:
                    accumulator = ram.get(operand) + accumulator;
                    break;
                case SUBTRACT:
                    accumulator= ram.get(operand) - accumulator;
                    break;
                case DIVIDE:
                    accumulator= ram.get(operand) /accumulator;
                    break;
                case MULTIPLY:
                    accumulator = ram.get(operand) * accumulator;
                    break;
            }
            
        }while( pointer < Ram.SIZE && operationCode != HALT );
    }

    /**
     * @return the accumulator
     */
    public int getAccumulator() {
        return accumulator;
    }

    /**
     * @return the pointer
     */
    public int getPointer() {
        return pointer;
    }

    /**
     * @return the instruction
     */
    public int getInstruction() {
        return instruction;
    }

    /**
     * @return the operationCode
     */
    public int getOperationCode() {
        return operationCode;
    }

    /**
     * @return the operand
     */
    public int getOperand() {
        return operand;
    }
}
